package com.tristia.entity;

import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

@Entity
@Table(name = "review")
@NamedQueries( { @NamedQuery(name = "Review.findAll", query = "SELECT p FROM Review p"),
	@NamedQuery(name = "Review.findReviewsByBookId", query = "SELECT p FROM Review p where p.book_id=:book_id")
	})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "review", propOrder = {
    "reviewText",
    "username",
    "profileImageURL",
    "datetime",
    "rating",
    "book_id",
    "user_id"
})
@XmlRootElement
public class Review extends Txt implements ItemInfo {

    private String reviewText;
    @Transient
    private String username;
    @Transient
    @XmlElement(name = "profile_image_url")
    private String profileImageURL;
	private Date datetime = Calendar.getInstance().getTime();
	@Transient
	private Float rating;
    private Long book_id;
    private Long user_id;
    @XmlTransient
    @ManyToOne
    @JoinColumn(name="book_id",insertable=false,updatable=false)
    private Book book;
    @XmlTransient
    @ManyToOne
    @JoinColumn(name="user_id",insertable=false,updatable=false)
    private User user;
	
    public Review() {
    }

    public Review(final String title, final long authorId) {
        super(title, authorId);
    }

	public String getReviewText() {
		return reviewText;
	}

	public void setReviewText(String reviewText) {
		this.reviewText = reviewText;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getProfileImageURL() {
		return profileImageURL;
	}

	public void setProfileImageURL(String profileImageURL) {
		this.profileImageURL = profileImageURL;
	}

	public Date getDatetime() {
		return datetime;
	}

	public void setDatetime(Date datetime) {
		this.datetime = datetime;
	}

	public Float getRating() {
		return rating;
	}

	public void setRating(Float rating) {
		this.rating = rating;
	}

	public Long getBook_id() {
		return book_id;
	}

	public void setBook_id(Long book_id) {
		this.book_id = book_id;
	}

	public Long getUser_id() {
		return user_id;
	}

	public void setUser_id(Long user_id) {
		this.user_id = user_id;
	}

	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((book_id == null) ? 0 : book_id.hashCode());
		result = prime * result
				+ ((datetime == null) ? 0 : datetime.hashCode());
		result = prime * result + ((rating == null) ? 0 : rating.hashCode());
		result = prime * result
				+ ((reviewText == null) ? 0 : reviewText.hashCode());
		result = prime * result + ((user_id == null) ? 0 : user_id.hashCode());
		result = prime * result
				+ ((username == null) ? 0 : username.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		Review other = (Review) obj;
		if (book_id == null) {
			if (other.book_id != null)
				return false;
		} else if (!book_id.equals(other.book_id))
			return false;
		if (datetime == null) {
			if (other.datetime != null)
				return false;
		} else if (!datetime.equals(other.datetime))
			return false;
		if (rating == null) {
			if (other.rating != null)
				return false;
		} else if (!rating.equals(other.rating))
			return false;
		if (reviewText == null) {
			if (other.reviewText != null)
				return false;
		} else if (!reviewText.equals(other.reviewText))
			return false;
		if (user_id == null) {
			if (other.user_id != null)
				return false;
		} else if (!user_id.equals(other.user_id))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}

	@Override
	public String toString() {
        return (new Formatter()).format(
                "{\"id\":\"%d\",\"title\":\"%s\",\"reviewText\":\"%s\"}",
                super.getId(), super.getTitle(), this.reviewText).toString();
	}
	
	@GET
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
    public Review produceXml() {
        return this;
    }

}
